#include <string.h>
#include <iostream>

using std::cout;
using std::endl;
using std::ostream;

//TODO:浅拷贝,写时复制
//
class CowString{
public:
    CowString()
        :_pstr(new char[1+4]()+4)
    {
        cout<<"CowString()"<<endl;
        *(int *)(_pstr-4) = 1;
    }

    CowString(const char*str)
        :_pstr(new char[strlen(str)+1+4]()+4)
    {
        cout<<"CowString(const char*)"<<endl;
        strcpy(_pstr,str);
        *(int *)(_pstr-4) = 1;
    }

    //析构
    ~CowString(){
        if(_pstr){
            if(--*(int *)(_pstr-4) == 0){
                delete [](_pstr-4);
            }
        }
    }

    //拷贝构造函数:浅拷贝
    CowString(const CowString &rhs)
        :_pstr(rhs._pstr)
    {
        cout<<"CowString(const CowString &)"<<endl;
        ++ *(int *)(_pstr-4) ;
    }

    //赋值运算符
    CowString &operator=(const CowString &rhs){
        if(this !=&rhs){
            if(--*(int *)(_pstr -4)==0){
                delete [](_pstr-4);
            }
            _pstr = rhs._pstr;
            ++*(int *)(_pstr-4);
        }
        return *this;
    }

    int refcount(){
        return *(int *)(_pstr-4);
    }

    const char*c_str(){
        return _pstr;
    }

    int size(){
        return strlen(_pstr);
    }


private: 
    /*---------------------------嵌套类开始----------------------------------*/
    class CharProxy{
    public:
        CharProxy(CowString &lhs,size_t index)
            :_str(lhs)
             ,_idx(index) 
        {

        }

        char & operator=(const char &ch){
            if(_idx>=_str.size()){
                static char nullchar = '\0';
                return nullchar;
            }
            if(_str._pstr[_idx] != ch ){
                if(_str.refcount() > 1)
                {
                    char *temp = new char[strlen(_str._pstr)+1+4]()+4;
                    --*(int *)( _str._pstr-4);
                    strcpy(temp,_str._pstr);
                    _str._pstr = temp;
                    *(int *) (_str._pstr-4) = 1;
                }
                _str._pstr[_idx] = ch;
            }
            return _str._pstr[_idx];
        }

        friend ostream &operator<<(ostream &os,const CowString::CharProxy &rhs);

    private:
        CowString & _str;
        size_t _idx;
    };
/*---------------------------嵌套类结束---------------------------------------------------*/
public:

    friend ostream &operator<<(ostream &os,const CowString::CharProxy &rhs);

    CharProxy operator[](size_t idx){
        return CharProxy(*this,idx);
    }

private:
    char *_pstr;
};

ostream &operator<<(ostream &os,const CowString::CharProxy &rhs){
    if(rhs._str.size()>=rhs._idx){
        static char nullchar = '\0';
        os<< nullchar;
    }else{
        os<<rhs._str._pstr[rhs._idx];
    }
    return os;
}


void test(){
    CowString c1 ;
    CowString c2 ="hello";
    cout<<c1.c_str()<<endl;
    cout<< c2.c_str()<<endl;
    c1=c2;
    cout<<c1.refcount()<<endl;
    cout<<c2.refcount()<<endl;
    CowString c3(c2);
    cout<<c3.refcount()<<endl;
    CowString c4 = "world";
    c3=c4;
    cout<<"-------------------------"<<endl;
    cout<<c1.refcount()<<endl;
    cout<<c3.refcount()<<endl;
    cout<<c4.refcount()<<endl;
}
void test2(){
    CowString c1 ="hello";
    cout<<c1[0]<<endl;
    c1[0] = 'H';
    c1[0];
    cout<<c1.c_str()<<endl;
    cout<<c1.refcount()<<endl;
}

int main()
{


    test2 ();
    return 0;
}

